/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package org.cip.esymons.tesoreria.beans;

import java.sql.SQLException;
import org.cip.esymons.general.util.ControladorAbstracto;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.ejb.EJB;
import javax.faces.model.SelectItem;
import org.cip.esymons.general.be.Empleado;
import org.cip.esymons.general.util.FormatoExportacion;
import org.cip.esymons.general.util.Reporteador;
import org.cip.esymons.tesoreria.bc.CajaChicaDelegate;
import org.cip.esymons.tesoreria.bc.ComprobanteEgresoDelegate;
import org.cip.esymons.tesoreria.bc.DetCajaChicaDelegate;
import org.cip.esymons.tesoreria.bc.EjecutarGeneracionCajaChicaLocal;
import org.cip.esymons.tesoreria.bc.EmpleadoDelegate;
import org.cip.esymons.tesoreria.bc.MovimientoCuentaDelegate;
import org.cip.esymons.tesoreria.be.CajaChica;
import org.cip.esymons.tesoreria.be.ComprobanteEgreso;
import org.cip.esymons.tesoreria.be.DetCajaChica;
import org.cip.esymons.tesoreria.be.EnumEstadoCajaChica;
import org.cip.esymons.tesoreria.be.EnumEstadoDetCajaChica;
import org.cip.esymons.tesoreria.be.EnumEstadoMovimiento;
import org.cip.esymons.tesoreria.be.EnumTipoCajaChica;
import org.cip.esymons.tesoreria.be.EnumTipoDeuda;
import org.cip.esymons.tesoreria.be.MovimientoCuenta;
import org.cip.esymons.tramite.be.DocumentoExterno;

/**
 *
 * @author Ingrid Capuñay
 */
public class CajaChicaController extends ControladorAbstracto {

    @EJB
    EjecutarGeneracionCajaChicaLocal delegado;
    private ComprobanteEgresoDelegate delegadoComprobanteEgreso;
    private CajaChicaDelegate delegadoCajaChica;
    private MovimientoCuentaDelegate delegadoMovimientoCuenta;
    private EmpleadoDelegate delegadoEmpleado;
    private DetCajaChicaDelegate detCajaChicaDelegate;
    private String dNIoCIP;
    private Long codigo;
    private Long codigoDetalle;
    private Long codigoDetalle2;
    private String nombreTipoDocumento;
    private int entregarDinero;
    private DetCajaChica detalleCajaChica;

    public CajaChicaController() {
        delegadoComprobanteEgreso = new ComprobanteEgresoDelegate();
        delegadoMovimientoCuenta = new MovimientoCuentaDelegate();
        delegadoCajaChica = new CajaChicaDelegate();
        delegadoEmpleado = new EmpleadoDelegate();
        detCajaChicaDelegate = new DetCajaChicaDelegate();
        
    }

    public String nuevo() {
        delegado.init();
        delegado.getRealizarGeneracionCajachicaLocal().inicializarCajachica();
        return "nuevo";
    }

    public Double getSaldoMasComprobante() {
        delegado.getRealizarGeneracionCajachicaLocal().getCajaChica().setCacDebe(0.0);
        if (delegado.getRealizarGeneracionCajachicaLocal().getComprobanteEgreso() != null) {
            delegado.getRealizarGeneracionCajachicaLocal().getCajaChica().setCacDebe(delegado.getRealizarGeneracionCajachicaLocal().getComprobanteEgreso().getHaber());
        }
        return delegado.getRealizarGeneracionCajachicaLocal().getCajaChica().getMonto() + delegado.getRealizarGeneracionCajachicaLocal().getCajaChica().getCacDebe();
    }

    public List<ComprobanteEgreso> getListaVouchersDisponibles() {
        if (delegado.getRealizarGeneracionCajachicaLocal().getListaVouchers() == null) {
            delegado.getRealizarGeneracionCajachicaLocal().setListaVouchers(delegadoComprobanteEgreso.vouchersDisponiblesCajaChica());
        }
        return delegado.getRealizarGeneracionCajachicaLocal().getListaVouchers();
    }

    public String fijarComprobante() {
        delegado.getRealizarGeneracionCajachicaLocal().setComprobanteEgreso(null);
        ComprobanteEgreso coe = null;
        for (ComprobanteEgreso ce : delegado.getRealizarGeneracionCajachicaLocal().getListaVouchers()) {
            if (ce.isSeleccionado()) {
                if (coe == null) {
                    coe = ce;
                } else {
                    warn("Debe escoger solo un comprobante.");
                    return null;
                }
            }
        }
        delegado.getRealizarGeneracionCajachicaLocal().setComprobanteEgreso(coe);
        return null;
    }

    public String grabar() {
        delegado.getRealizarGeneracionCajachicaLocal().grabar();
        ControladorAbstracto.info("Se registró con éxito la nueva Caja Chica. Para Acceder a ella ir a la Carpeta Búsquedas del Módulo de Tesorería");
        return "buscar";
    }

    public String agregarDetalle() {
        CajaChica cc = delegadoCajaChica.find(codigo);
        Double montoTotalCajaDebe = cc.getCacDebe();
        List<DetCajaChica> detCaja = detCajaChicaDelegate.econtrarDetalle(cc.getCacCodigo());
        Double sumaDetCaja = 0.00;
        for (DetCajaChica detCajaChica : detCaja) {
            if (!detCajaChica.getEstado().equals(EnumEstadoDetCajaChica.ANULADO)) {
                if (detCajaChica.getDecHaber() != null) {
                    sumaDetCaja = sumaDetCaja + detCajaChica.getDecHaber();
                }
            }
        }
        if (sumaDetCaja.equals(montoTotalCajaDebe)) {
            ControladorAbstracto.info("Suma de Montos de Detalles Alcanzó Monto Total Fijado para Caja Chica. No puede Agregar otro Detalle.");
            return null;
        }
        if (cc.getEstadoCajaChica().equals(EnumEstadoCajaChica.ACTIVA)) {
            delegado.init();
            cc.setCacSaldoAnterior(montoTotalCajaDebe - sumaDetCaja);
            delegado.getRealizarGeneracionCajachicaLocal().getDetCajaChica().setCajaChica(cc);
            delegado.getRealizarGeneracionCajachicaLocal().getDetCajaChica().setDecFecha(new Date());
            delegado.getRealizarGeneracionCajachicaLocal().getDetCajaChica().setEstado(EnumEstadoDetCajaChica.ACTIVO);
            delegado.getRealizarGeneracionCajachicaLocal().getDetCajaChica().setDocumentoComprobante(new DocumentoExterno());
            Double montoRestanteCaja = 0.00;
            montoRestanteCaja = montoTotalCajaDebe - sumaDetCaja;
            ControladorAbstracto.info("Sólo le queda un Saldo de " + montoRestanteCaja);
            return "agregar_detalle";

        } else {
            ControladorAbstracto.info("La Caja Chica debe estar ACTIVA para Agregar un Detalle");
            return null;
        }
    }

    public String iniciarCerradoCaja() {
        codigo = Long.decode(getRequestParameter("codigo"));
        delegado.init();
        delegado.getRealizarGeneracionCajachicaLocal().setCajaChica(delegadoCajaChica.find(codigo));
        return null;
    }

    public String cancelarCerradoCaja() {
        delegado.getRealizarGeneracionCajachicaLocal().cancelar();
        return null;
    }
   
    public String cerrarCaja() {
        CajaChica cc = delegado.getRealizarGeneracionCajachicaLocal().getCajaChica();
        Double montoTotalCajaDebe = cc.getCacDebe();
        List<DetCajaChica> detCaja = detCajaChicaDelegate.econtrarDetalle(cc.getCacCodigo());
        Double sumaDetCaja = 0.00;
        for (DetCajaChica detCajaChica : detCaja) {
            if (!detCajaChica.getEstado().equals(EnumEstadoDetCajaChica.ANULADO)) {
                if(detCajaChica.getDecHaber()!=null){
                    sumaDetCaja = sumaDetCaja + detCajaChica.getDecHaber();
                }
            }
        }
        if (cc.getEstadoCajaChica().equals(EnumEstadoCajaChica.ACTIVA)) {
            Double montoRestanteCaja = 0.00;
            montoRestanteCaja = montoTotalCajaDebe - sumaDetCaja;
            cc.setEstadoCajaChica(EnumEstadoCajaChica.CERRADA);
            cc.setCacFecCierre(new Date());
            if (montoRestanteCaja <= 0) {
                cc.setCacHaber(cc.getCacDebe());

            } else {
                if (entregarDinero == 0) {
                    cc.setCacHaber(sumaDetCaja);
                } else {
                    Calendar cal = Calendar.getInstance();
                    cal.setTime(new Date());
                    MovimientoCuenta mc = new MovimientoCuenta();
                    mc.setDescripcion("Devolucion de Caja Chica");
                    mc.setEstado(EnumEstadoMovimiento.Impaga);
                    mc.setFkSolCodigo(cc.getResponsable().getPersonaNatural());
                    mc.setMcuAnio(cal.get(Calendar.YEAR));
                    mc.setMcuFechvencimiento(cal.getTime());
                    mc.setMcuMes(cal.get(Calendar.MONTH) + 1);
                    mc.setMcuMonto(montoRestanteCaja);
                    mc.setMcuSaldo(montoRestanteCaja);
                    mc.setTipoDeuda(EnumTipoDeuda.OTROS);
                    delegadoMovimientoCuenta.create(mc);
                }
            }
            delegadoCajaChica.edit(cc);
            ControladorAbstracto.info("Se ha cerrado satisfactoriamente la caja.");
            return null;

        } else {
            ControladorAbstracto.info("La Caja Chica debe estar ACTIVA para ser Cerrada.");
            return null;
        }
    }

    public String grabarDetalle() {
        if (delegado.getRealizarGeneracionCajachicaLocal().getTipoDetalle() == 0) {//egreso
            Double montoTotalCajaDebe = delegado.getRealizarGeneracionCajachicaLocal().getDetCajaChica().getCajaChica().getCacDebe();
            List<DetCajaChica> detCaja = detCajaChicaDelegate.econtrarDetalle(delegado.getRealizarGeneracionCajachicaLocal().getDetCajaChica().getCajaChica().getCacCodigo());
            Double sumaDetCaja = 0.00;
            for (DetCajaChica detCajaChica : detCaja) {
                if (!detCajaChica.getEstado().equals(EnumEstadoDetCajaChica.ANULADO)) {
                    if (detCajaChica.getDecHaber() != null) {
                        sumaDetCaja = sumaDetCaja + detCajaChica.getDecHaber();
                    }
                }
            }
            Double nuevaSumaDetCaja = 0.00;
            nuevaSumaDetCaja = sumaDetCaja + delegado.getRealizarGeneracionCajachicaLocal().getDetCajaChica().getDecHaber();

            if (nuevaSumaDetCaja.compareTo(montoTotalCajaDebe) > 0) {
                ControladorAbstracto.info("Monto a Agregar supera el Monto Total Fijado para la Caja Chica. Ingrese otro Monto menor.");
                return null;
            }
            delegado.getRealizarGeneracionCajachicaLocal().getDetCajaChica().getCajaChica().setCacSaldoAnterior(delegado.getRealizarGeneracionCajachicaLocal().getDetCajaChica().getCajaChica().getCacSaldoAnterior()-delegado.getRealizarGeneracionCajachicaLocal().getDetCajaChica().getDecHaber());
            delegado.getRealizarGeneracionCajachicaLocal().getDetCajaChica().setSaldoCajaChica(delegado.getRealizarGeneracionCajachicaLocal().getDetCajaChica().getCajaChica().getCacSaldoAnterior());
            delegado.getRealizarGeneracionCajachicaLocal().getDetCajaChica().getDocumentoComprobante().setDocFecha(new Date());
            delegado.getRealizarGeneracionCajachicaLocal().getDetCajaChica().getDocumentoComprobante().setFkSolCodigo(delegado.getRealizarGeneracionCajachicaLocal().getDetCajaChica().getSolicitante());
        }
        delegado.getRealizarGeneracionCajachicaLocal().grabarDetalle();
        return "ver_detalle_caja";
    }

    public String verDetalleCaja() {       
        return "ver_detalle_caja";
    }

    /**CODIGO DE REPORTES DE DETALLES DE GASTOS DE LA CAJA CHICA SELECCIONADA*/
    public String reporteDetallesCajaChica() throws SQLException {
        
            List<DetCajaChica> listaDetallesCaja = detCajaChicaDelegate.econtrarDetalle(codigo);
            Map param = new HashMap();
            Double sumaDetCaja = 0.00;
            Double montoCaja = 0.00;
            for (DetCajaChica detCajaChica : listaDetallesCaja) {
                if(montoCaja.equals(0.00)){
                    montoCaja = detCajaChica.getCajaChica().getMontoRecibido();
                    if(detCajaChica.getCajaChica().getCacSaldoAnterior()!=null){
                        montoCaja +=detCajaChica.getCajaChica().getCacSaldoAnterior();
                    }
                }
                if (!detCajaChica.getEstado().equals(EnumEstadoDetCajaChica.ANULADO)) {
                    if (detCajaChica.getDecHaber() != null) {
                        sumaDetCaja = sumaDetCaja + detCajaChica.getDecHaber();
                    }
                }
            }
            param.put("gastos", sumaDetCaja);
            param.put("saldo", montoCaja-sumaDetCaja);
            if (listaDetallesCaja != null) {
                if (listaDetallesCaja.size() > 0) {
                    Reporteador reporteador = new Reporteador();
                    reporteador.exportarReporte("rptCajaChica", FormatoExportacion.pdf, listaDetallesCaja, param);
                }else{
                    ControladorAbstracto.warn("La Caja Chica no tiene detalles a Mostrar");
                }
            }       
            return null;
    }

    public String anularCajaChica() {
        Long codigo2 = Long.decode(ControladorAbstracto.getRequestParameter("codigo"));
        CajaChica cc = delegadoCajaChica.find(codigo2);
        cc.setEstadoCajaChica(EnumEstadoCajaChica.ANULADA);
        delegadoCajaChica.edit(cc);
        ControladorAbstracto.info("Se Actualizó Correctamente Caja Chica");
        return null;
    }

    public String anularDetalleCajaChica() {
        try {
            codigoDetalle = Long.decode(getRequestParameter("codigoDet"));
            DetCajaChica detCC = detCajaChicaDelegate.find(codigoDetalle);
            detCC.setEstado(EnumEstadoDetCajaChica.ANULADO);
            detCajaChicaDelegate.edit(detCC);
            ControladorAbstracto.info("Se Actualizó Correctamente Detalle de Caja");
        } catch (Exception e) {
            ControladorAbstracto.info("Error");
        }

        return null;
    }

    public String cambiarFechaDetalleCajaChica() {
        try {
            codigoDetalle = Long.decode(getRequestParameter("codigoDet"));
            delegado.getRealizarGeneracionCajachicaLocal().setDetCajaChica(detCajaChicaDelegate.find(codigoDetalle));
        } catch (Exception e) {
            ControladorAbstracto.info("Error");
        }

        return null;
    }

    public String grabarCambioFechaDetalleCajaChica() {
        try {
            detCajaChicaDelegate.edit(delegado.getRealizarGeneracionCajachicaLocal().getDetCajaChica());
            ControladorAbstracto.info("Se Actualizó la Fecha Correctamente Detalle de Caja");
        } catch (Exception e) {
            ControladorAbstracto.info("Error");
        }

        return null;
    }

    public String actualizarDetalleCajaChica() {
        try {
            codigoDetalle2 = Long.decode(getRequestParameter("codigoDet"));
            DetCajaChica detCC = detCajaChicaDelegate.find(codigoDetalle2);
            detCajaChicaDelegate.edit(detCC);
            ControladorAbstracto.info("Se Actualizó Correctamente Detalle de Caja");
        } catch (Exception e) {
            ControladorAbstracto.info("Error");
        }

        return null;
    }

    public String buscarSolicitante() {
        delegado.getRealizarGeneracionCajachicaLocal().buscarSolicitante(getdNIoCIP());
        return null;
    }

    public List<DetCajaChica> getListaDetalleCajaChica() {
        try {
            return detCajaChicaDelegate.econtrarDetalle(codigo);
        } catch (Exception ex) {
            return new ArrayList<DetCajaChica>();
        }
    }

    public List<CajaChica> getListarCajasChicas() {
        try {
            return delegadoCajaChica.findAll();
        } catch (Exception ex) {
            return new ArrayList();
        }
    }

    //metodo nuevo
    public List<Empleado> autocompletarResponsables(Object event) {
        List<Empleado> lista = new ArrayList();
        String cond = event.toString().toUpperCase();
        try {
            lista = delegadoEmpleado.listarEmpleadosPorCondicion(cond);
        } catch (Exception ex) {
            error(ex.toString());
        }
        return lista;
    }

    public SelectItem[] getTipoCajaChicaItems() {
        try {
            SelectItem[] select = new SelectItem[EnumTipoCajaChica.values().length];
            int cont = 0;
            for (EnumTipoCajaChica e : EnumTipoCajaChica.values()) {
                select[cont] = new SelectItem(e, e.name());
                cont++;
            }
            return select;
        } catch (Exception ex) {
            SelectItem[] select = new SelectItem[1];
            select[0] = new SelectItem(null, "No existen Tipos");
            return select;
        }
    }

    public SelectItem[] getEstadosCajaChicaItems() {
        try {
            SelectItem[] select = new SelectItem[EnumEstadoCajaChica.values().length];
            int cont = 0;
            for (EnumEstadoCajaChica e : EnumEstadoCajaChica.values()) {
                select[cont] = new SelectItem(e, e.name());
                cont++;
            }
            return select;
        } catch (Exception ex) {
            SelectItem[] select = new SelectItem[1];
            select[0] = new SelectItem(null, "No existen Estados");
            return select;
        }
    }

    /**
     * @return the cajaChica
     */
    public CajaChica getCajaChica() {
        return delegado.getRealizarGeneracionCajachicaLocal().getCajaChica();
    }

    /**
     * @param cajaChica the cajaChica to set
     */
    public void setCajaChica(CajaChica cajaChica) {
        delegado.getRealizarGeneracionCajachicaLocal().setCajaChica(cajaChica);
    }

    /**
     * @return the nombreResponsable
     */
    public String getNombreResponsable() {
        return delegado.getRealizarGeneracionCajachicaLocal().getNombreResponsable();
    }

    /**
     * @param nombreResponsable the nombreResponsable to set
     */
    public void setNombreResponsable(String nombreResponsable) {
        delegado.getRealizarGeneracionCajachicaLocal().setNombreResponsable(nombreResponsable);
    }

    /**
     * @return the detCajaChica
     */
    public DetCajaChica getDetCajaChica() {
        try{
            return delegado.getRealizarGeneracionCajachicaLocal().getDetCajaChica();
        }catch(Exception e){
            return new DetCajaChica();

        }
    }

    /**
     * @param detCajaChica the detCajaChica to set
     */
    public void setDetCajaChica(DetCajaChica detCajaChica) {
        delegado.getRealizarGeneracionCajachicaLocal().setDetCajaChica(detCajaChica);
    }

    public int getBuscarSolicitantePor() {
        return delegado.getRealizarGeneracionCajachicaLocal().getBuscarSolicitantePor();
    }

    public void setBuscarSolicitantePor(int buscarSolicitantePor) {
        delegado.getRealizarGeneracionCajachicaLocal().setBuscarSolicitantePor(buscarSolicitantePor);
    }

    /**
     * @return the dNIoCIP
     */
    public String getdNIoCIP() {
        return dNIoCIP;
    }

    /**
     * @param dNIoCIP the dNIoCIP to set
     */
    public void setdNIoCIP(String dNIoCIP) {
        this.dNIoCIP = dNIoCIP;
    }

    public Long getCodigo() {
        try {
            codigo = Long.decode(getRequestParameter("codigo"));
        } catch (Exception ex) {
            System.out.println("Error codigo mal");
        }
        return codigo;
    }

    public void setCodigo(Long codigo) {
        this.codigo = codigo;
    }

    /**
     * @return the nombreTipoDocumento
     */
    public String getNombreTipoDocumento() {
        return nombreTipoDocumento;
    }

    /**
     * @param nombreTipoDocumento the nombreTipoDocumento to set
     */
    public void setNombreTipoDocumento(String nombreTipoDocumento) {
        this.nombreTipoDocumento = nombreTipoDocumento;
    }

    /**
     * @return the codigoDetalle
     */
    public Long getCodigoDetalle() {
        return codigoDetalle;
    }

    /**
     * @param codigoDetalle the codigoDetalle to set
     */
    public void setCodigoDetalle(Long codigoDetalle) {
        this.codigoDetalle = codigoDetalle;
    }

    /**
     * @return the entregarDinero
     */
    public int getEntregarDinero() {
        return entregarDinero;
    }

    /**
     * @param entregarDinero the entregarDinero to set
     */
    public void setEntregarDinero(int entregarDinero) {
        this.entregarDinero = entregarDinero;
    }

    /**
     * @return the tipoDetalle
     */
    public int getTipoDetalle() {
        return delegado.getRealizarGeneracionCajachicaLocal().getTipoDetalle();
    }

    /**
     * @param tipoDetalle the tipoDetalle to set
     */
    public void setTipoDetalle(int tipoDetalle) {
        delegado.getRealizarGeneracionCajachicaLocal().setTipoDetalle(tipoDetalle);
    }

    /**
     * @return the codigoDetalle2
     */
    public Long getCodigoDetalle2() {
        return codigoDetalle2;
    }

    /**
     * @param codigoDetalle2 the codigoDetalle2 to set
     */
    public void setCodigoDetalle2(Long codigoDetalle2) {
        this.codigoDetalle2 = codigoDetalle2;
    }

    /**
     * @return the detalleCajaChica
     */
    public DetCajaChica getDetalleCajaChica() {
        return detalleCajaChica;
    }

    /**
     * @param detalleCajaChica the detalleCajaChica to set
     */
    public void setDetalleCajaChica(DetCajaChica detalleCajaChica) {
        this.detalleCajaChica = detalleCajaChica;
    }
}
